home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / SWAG / SWAGA_C / COMM.SWG / 0046_Windows ASYNC unit.pas < prev    next >
Pascal/Delphi Source File  |  1994-08-24  |  61KB  |  1,319 lines

  1. {---------------------------------------------------------}
  2. {  Project : Async12 for Windows                          }
  3. {  By      : Ir. G.W van der Vegt                         }
  4. {---------------------------------------------------------}
  5. {  Based on the following TP product :                    }
  6. {                                                         }
  7. {  ASYNC12 - Interrupt-driven asyncronous                 }
  8. {            communications for Turbo Pascal.             }
  9. {                                                         }
  10. {            Version 1.2 - Wedensday June 14, 1989        }
  11. {            Copyright (C) 1989, Rising Edge Data Services}
  12. {                                                         }
  13. {            Permission is granted for non-commercial     }
  14. {            use and distribution.                        }
  15. {                                                         }
  16. {            Author : Mark Schultz                        }
  17. {                                                         }
  18. {---------------------------------------------------------}
  19. {                                                         }
  20. { -Because of the complex nature of serial I/O not all    }
  21. {  routines are 100% tested. I don't feel/am/will ever be }
  22. {  responsible for any damage caused by this routines.    }
  23. {                                                         }
  24. { -Some routines don't work (yet) because some fields are }
  25. {  mentioned in the BP7 help file but are missing in      }
  26. {  Wintypes. The routines are SetCTSmode, SetRTSMode &    }
  27. {  SoftHandshake.                                         }
  28. {                                                         }
  29. { -Some routines can't be implemented in windows. They    }
  30. {  are listed behind the end.                             }
  31. {                                                         }
  32. { -From the original ASYNC12 code, only the syntax, some  }
  33. {  high level pascal code and pieces of comment are used. }
  34. {  Due to the different way windows handels devices, all  }
  35. {  assembly codes couldn't be reused and was rewritten in }
  36. {  Borland Pascal. I used parts of ASYNC12 because I find }
  37. {  it a very complete package for Serial I/O and it works }
  38. {  very well too. Sources were supplied and documented    }
  39. {  very well.                                             }
  40. {                                                         }
  41. {---------------------------------------------------------}
  42. {  Date   .Time  Revision                                 }
  43. {  ------- ----  ---------------------------------------- }
  44. {  9406017.1200  Creation.                                }
  45. {---------------------------------------------------------}
  46.  
  47. Library Async12w;
  48.  
  49. Uses
  50.   Winprocs,
  51.   Wintypes;
  52.  
  53. {****************************************************************************}
  54.  
  55. {----Public definition section}
  56.  
  57. TYPE
  58.   T_eoln     = (C_cr,C_lf);
  59.  
  60. CONST
  61.   C_MaxCom   = 4;                   {----Supports COM1..COM4}
  62.   C_MinBaud  = 110;
  63.   C_MaxBaud  = 256000;
  64.  
  65. TYPE
  66.   C_ports      = 1..C_MaxCom;       {----Subrange type to minimize programming errors}
  67.  
  68. {****************************************************************************}
  69.  
  70. {----Private definition section}
  71.  
  72. CONST
  73.   portopen   : Array[C_ports] OF Boolean = (false,false,false,false);   {----Open port flags    }
  74.   cids       : ARRAY[C_ports] OF Integer = (-1,-1,-1,-1);               {----Device ID's        }
  75.   inbs       : ARRAY[C_ports] OF Word    = ( 0, 0, 0, 0);               {----Input  buffer sizes}
  76.   outbs      : ARRAY[C_ports] OF Word    = ( 0, 0, 0, 0);               {----Output buffer sizes}
  77.   txdir      = 0;                                                       {----Used for FlushCom  }
  78.   rxdir      = 1;                                                       {----Used for FlushCom  }
  79.   fon        = 1;                                                       {----Used for Handshakes}
  80.   foff       = 0;                                                       {----Used for Handshakes}
  81.   eolns      : ARRAY[C_ports] OF T_eoln  = (C_cr,C_cr,C_cr,C_cr);       {----Eoln characters    }
  82.  
  83. VAR
  84. {----Don't seem to be declared in Wintypes, neccesary to fake}
  85.   foutx,
  86.   foutxCTSflow,
  87.   fRTSflow   : Byte;
  88.  
  89. {****************************************************************************}
  90. {*                                                                          *}
  91. {*  Procedure ComReadCh(ComPort:Byte) : Char; External;                     *}
  92. {*                                                                          *}
  93. {*  ComPort:Byte  ->  Port # to use (1 - C_MaxCom)                          *}
  94. {*                                                                          *}
  95. {*  Returns character from input buffer of specified port.  If the buffer   *}
  96. {*  is empty, the port # invalid or not opened, a Chr(0) is returned.       *}
  97. {*                                                                          *}
  98. {****************************************************************************}
  99.  
  100. Function ComReadCh(comport:C_ports) : Char; Export;
  101.  
  102. Var
  103.   stat : TComStat;
  104.   ch   : Char;
  105.   cid  : Integer;
  106.  
  107. Begin
  108.   ComReadCh:=#0;
  109.  
  110.   If (ComPort IN [1..C_MaxCom]) And
  111.      (portopen[ComPort])
  112.     Then
  113.       Begin
  114.         cid:=cids[comport];
  115.  
  116.       {----See how many characters are in the rx buffer}
  117.         If (GetCommError(cid,stat)=0) AND
  118.            (stat.cbInQue>0)           AND
  119.            (ReadComm(cid,@ch,1)=1)
  120.           THEN ComReadCh:=ch;
  121.       End;
  122. END; {of ComReadCh}
  123.  
  124. {****************************************************************************}
  125. {*                                                                          *}
  126. {*  Function ComReadChW(ComPort:Byte) : Char; External;                     *}
  127. {*                                                                          *}
  128. {*  ComPort:Byte  ->  Port # to use (1 - C_MaxCom)                          *}
  129. {*                                                                          *}
  130. {*  Works like ComReadCh, but will wait until at least 1 character is       *}
  131. {*  present in the specified input buffer before exiting.  Thus, ComReadChW *}
  132. {*  works much like the ReadKey predefined function.                        *}
  133. {*                                                                          *}
  134. {****************************************************************************}
  135.  
  136. Function ComReadChW(comport:C_ports) : Char; Export;
  137.  
  138. Var
  139.   stat : TComStat;
  140.   ch   : Char;
  141.   ok   : Boolean;
  142.   cid  : Integer;
  143.  
  144. Begin
  145.   ComReadChW:=#00;
  146.  
  147.   If (ComPort IN [1..C_MaxCom]) And
  148.      (portopen[ComPort])
  149.     Then
  150.       Begin
  151.         cid:=cids[comport];
  152.         ok :=false;
  153.  
  154.       {----See how many characters are in the rx buffer}
  155.         REPEAT
  156.           IF (GetCommError(cid,stat)<>0)
  157.             THEN ok:=True
  158.             ELSE
  159.               BEGIN
  160.                 IF (stat.cbInQue<>0)       AND
  161.                    (ReadComm(cid,@ch,1)=1)
  162.                   THEN ComReadChW:=ch;
  163.                 ok:=true;
  164.               END;
  165.         UNTIL ok;
  166.       End;
  167. END; {of ComReadChW}
  168.  
  169. {****************************************************************************}
  170. {*                                                                          *}
  171. {*  Procedure ComWriteCh(ComPort:Byte; Ch:Char); External                   *}
  172. {*                                                                          *}
  173. {*  ComPort:Byte  ->  Port # to use (1 - C_MaxCom)                          *}
  174. {*  Ch:Char       ->  Character to send                                     *}
  175. {*                                                                          *}
  176. {*  Places the character [Ch] in the transmit buffer of the specified port. *}
  177. {*  If the port specified is not open or nonexistent, or if the buffer is   *}
  178. {*  filled, the character is discarded.                                     *}
  179. {*                                                                          *}
  180. {****************************************************************************}
  181.  
  182. Procedure ComWriteCh(comport:C_ports; Ch:Char); Export;
  183.  
  184. VAR
  185.   stat : TComStat;
  186.   cid  : Integer;
  187.  
  188. BEGIN
  189.   If (ComPort IN [1..C_MaxCom]) And
  190.      (portopen[ComPort])
  191.     Then
  192.       Begin
  193.         cid:=cids[comport];
  194.  
  195.         IF (GetCommError(cid,stat)=0)   AND
  196.            (stat.cbOutQue<outbs[comport])
  197.           THEN TransmitCommChar(cid,ch);
  198.       End;
  199. END; {of CommWriteCh}
  200.  
  201. {****************************************************************************}
  202. {*                                                                          *}
  203. {*  Procedure ComWriteChW(ComPort:Byte; Ch:Char); External;                 *}
  204. {*                                                                          *}
  205. {*  ComPort:Byte  ->  Port # to use (1 - C_MaxCom)                          *}
  206. {*  Ch:Char       ->  Character to send                                     *}
  207. {*                                                                          *}
  208. {*  Works as ComWriteCh, but will wait until at least 1 free position is    *}
  209. {*  available in the output buffer before attempting to place the character *}
  210. {*  [Ch] in it.  Allows the programmer to send characters without regard to *}
  211. {*  available buffer space.                                                 *}
  212. {*                                                                          *}
  213. {****************************************************************************}
  214.  
  215. Procedure ComWriteChW(comport:C_ports; Ch:Char); Export;
  216.  
  217. VAR
  218.   stat : TComStat;
  219.   cid  : Integer;
  220.   rdy  : Boolean;
  221.  
  222. BEGIN
  223.   If (ComPort IN [1..C_MaxCom]) And
  224.      (portopen[ComPort])
  225.     Then
  226.       Begin
  227.         cid:=cids[comport];
  228.         rdy:=False;
  229.  
  230.         REPEAT
  231.           IF (GetCommError(cid,stat)<>0)
  232.             THEN rdy:=true
  233.             ELSE
  234.               IF (stat.cbOutQue<outbs[comport])
  235.                 THEN rdy:=TransmitCommChar(cid,ch)=0;
  236.         UNTIL rdy;
  237.       End;
  238. End; {of ComWriteChW}
  239.  
  240. {****************************************************************************}
  241. {*                                                                          *}
  242. {*  Procedure ClearCom(ComPort:Byte); IO:Char)                              *}
  243. {*                                                                          *}
  244. {*  ComPort:Byte  ->  Port # to use (1 - C_MaxCom).                         *}
  245. {*                    Request ignored if out of range or unopened.          *}
  246. {*  IO:Char       ->  Action code; I=Input, O=Output, B=Both                *}
  247. {*                    No action taken if action code unrecognized.          *}
  248. {*                                                                          *}
  249. {*  ClearCom allows the user to completely clear the contents of either     *}
  250. {*  the input (receive) and/or output (transmit) buffers.  The "action      *}
  251. {*  code" passed in <IO> determines if the input (I) or output (O) buffer   *}
  252. {*  is cleared.  Action code (B) will clear both buffers.  This is useful   *}
  253. {*  if you wish to cancel a transmitted message or ignore part of a         *}
  254. {*  received message.                                                       *}
  255. {*                                                                          *}
  256. {****************************************************************************}
  257.  
  258. Procedure ClearCom(ComPort:C_Ports;IO:Char); Export;
  259.  
  260. Var
  261.   cid  : Integer;
  262.  
  263. Begin
  264.   If (ComPort IN [1..C_MaxCom]) And
  265.      (portopen[ComPort])
  266.     Then
  267.       Begin
  268.         cid:=cids[comport];
  269.  
  270.         Case Upcase(IO) OF
  271.           'I' : FlushComm(cid,rxdir);
  272.           'B' : Begin
  273.                   FlushComm(cid,rxdir);
  274.                   FlushComm(cid,txdir);
  275.                 End;
  276.           'O' : FlushComm(cid,txdir);
  277.         End;
  278.       End;
  279. End; {of ClearComm}
  280.  
  281. {****************************************************************************}
  282. {*                                                                          *}
  283. {*  Procedure ComBufferLeft(ComPort:Byte; IO:Char) : Word                   *}
  284. {*                                                                          *}
  285. {*  ComPort:Byte  ->  Port # to use (1 - C_MaxCom).                         *}
  286. {*                    Returns 0 if Port # invalid or unopened.              *}
  287. {*  IO:Char       ->  Action code; I=Input, O=Output                        *}
  288. {*                    Returns 0 if action code unrecognized.                *}
  289. {*                                                                          *}
  290. {*  ComBufferLeft will return a number (bytes) indicating how much space    *}
  291. {*  remains in the selected buffer.  The INPUT buffer is checked if <IO> is *}
  292. {*  (I), and the output buffer is interrogated when <IO> is (O).  Any other *}
  293. {*  "action code" will return a result of 0.  Use this function when it is  *}
  294. {*  important to avoid program delays due to calls to output procedures or  *}
  295. {*  to prioritize the reception of data (to prevent overflows).             *}
  296. {*                                                                          *}
  297. {****************************************************************************}
  298.  
  299. Function ComBufferLeft(ComPort:C_ports; IO:Char) : Word; Export;
  300.  
  301. VAR
  302.   stat : TComStat;
  303.   cid  : Integer;
  304.  
  305. Begin
  306.   ComBufferLeft := 0;
  307.  
  308.   If (ComPort IN [1..C_MaxCom]) And
  309.      (portopen[ComPort])
  310.     Then
  311.       Begin
  312.         cid:=cids[comport];
  313.  
  314.         IF (GetCommError(cid,stat)=0)
  315.           THEN
  316.             CASE Upcase(IO) OF
  317.               'I' : ComBufferLeft:=inbs [comport]-stat.cbInQue;
  318.               'O' : ComBufferLeft:=outbs[comport]-stat.cbOutQue;
  319.             END;
  320.       End;
  321. End; {ComBufferLeft}
  322.  
  323. {****************************************************************************}
  324. {*                                                                          *}
  325. {*  Procedure ComWaitForClear(ComPort:Byte)                                 *}
  326. {*                                                                          *}
  327. {*  ComPort:Byte  ->  Port # to use (1 - C_MaxCom).                         *}
  328. {*                    Exits immediately if out of range or port unopened.   *}
  329. {*                                                                          *}
  330. {*  A call to ComWaitForClear will stop processing until the selected out-  *}
  331. {*  put buffer is completely emptied.  Typically used just before a call    *}
  332. {*  to the CloseCom procedure to prevent premature cut-off of messages in   *}
  333. {*  transit.                                                                *}
  334. {*                                                                          *}
  335. {****************************************************************************}
  336.  
  337. Procedure ComWaitForClear(ComPort:C_ports); Export;
  338.  
  339. Var
  340.   stat  : TComStat;
  341.   cid   : Integer;
  342.   Empty : Boolean;
  343.  
  344. Begin
  345.   If (ComPort IN [1..C_MaxCom]) And
  346.      (portopen[ComPort])
  347.     Then
  348.       Begin
  349.         cid  :=cids[comport];
  350.         empty:=false;
  351.  
  352.         REPEAT
  353.           IF (GetCommError(cid,stat)<>0)
  354.             THEN empty:=true
  355.             ELSE empty:=stat.cbOutQue=0
  356.         UNTIL empty;
  357.       End;
  358. End; {ComWaitForClear}
  359.  
  360. {****************************************************************************}
  361. {*                                                                          *}
  362. {*  Procedure ComWrite(ComPort:Byte; St:String)                             *}
  363. {*                                                                          *}
  364. {*  ComPort:Byte  ->  Port # to use (1 - C_MaxCom).                         *}
  365. {*                    Exits immediately if out of range or port unopened.   *}
  366. {*  St:String     ->  String to send                                        *}
  367. {*                                                                          *}
  368. {*  Sends string <St> out communications port <ComPort>.                    *}
  369. {*                                                                          *}
  370. {****************************************************************************}
  371.  
  372. Procedure ComWrite(ComPort:C_ports; St:String); Export;
  373.  
  374. Var
  375.   X : Byte;
  376.  
  377. Begin
  378.   If (ComPort IN [1..C_MaxCom]) And
  379.      (portopen[ComPort])
  380.     Then
  381.       For X := 1 To Length(St) Do
  382.         ComWriteChW(ComPort,St[X]);
  383. End; {of ComWrite}
  384.  
  385. {****************************************************************************}
  386. {*                                                                          *}
  387. {*  Procedure ComWriteln(ComPort:Byte; St:String);                          *}
  388. {*                                                                          *}
  389. {*  ComPort:Byte  ->  Port # to use (1 - C_MaxCom).                         *}
  390. {*                    Exits immediately if out of range or port unopened.   *}
  391. {*  St:String     ->  String to send                                        *}
  392. {*                                                                          *}
  393. {*  Sends string <St> with a CR and LF appended.                            *}
  394. {*                                                                          *}
  395. {****************************************************************************}
  396.  
  397. Procedure ComWriteln(ComPort:C_ports; St:String); Export;
  398.  
  399. Var
  400.   X : Byte;
  401.  
  402. Begin
  403.   If (ComPort IN [1..C_MaxCom]) And
  404.      (portopen[ComPort])
  405.     Then
  406.       Begin
  407.         For X := 1 To Length(St) Do
  408.           ComWriteChW(ComPort,St[X]);
  409.         ComWriteChW(ComPort,#13);
  410.         ComWriteChW(ComPort,#10);
  411.       End;
  412. End; {of ComWriteln}
  413.  
  414. {****************************************************************************}
  415. {*                                                                          *}
  416. {*  Procedure Delay(ms:word);                                               *}
  417. {*                                                                          *}
  418. {*  ms:word       ->  Number of msec to wait.                               *}
  419. {*                                                                          *}
  420. {*  A substitute for CRT's Delay under DOS. This one will wait for at least *}
  421. {*  the amount of msec specified, probably even more because of the task-   *)
  422. {*  switching nature of Windows. So a msec can end up as a second if ALT-TAB*}
  423. {*  or something like is pressed. Minumum delays are guaranteed independend *}
  424. {*  of task-switches.                                                       *}
  425. {*                                                                          *}
  426. {****************************************************************************}
  427.  
  428. Procedure Delay(ms : Word);
  429.  
  430. Var
  431.   theend,
  432.   marker  : Longint;
  433.  
  434. Begin
  435. {----Potentional overflow if windows runs for 49 days without a stop}
  436.   marker:=GetTickCount;
  437. {$R-}
  438.   theend:=Longint(marker+ms);
  439. {$R+}
  440.  
  441. {----First see if timer overrun will occure and wait for this,
  442.      then test as usual}
  443.   If (theend<marker)
  444.     Then
  445.       While (GetTickCount>=0) DO;
  446.  
  447. {----Wait for projected time to pass}
  448.   While (theend>=GettickCount) Do;
  449. End; {of Delay}
  450.  
  451. {****************************************************************************}
  452. {*                                                                          *}
  453. {*  Procedure ComWriteWithDelay(ComPort:Byte; St:String; Dly:Word);         *}
  454. {*                                                                          *}
  455. {*  ComPort:Byte  ->  Port # to use (1 - C_MaxCom).                         *}
  456. {*                    Exits immediately if out of range or port unopened.   *}
  457. {*  St:String     ->  String to send                                        *}
  458. {*  Dly:Word      ->  Time, in milliseconds, to delay between each char.    *}
  459. {*                                                                          *}
  460. {*  ComWriteWithDelay will send string <St> to port <ComPort>, delaying     *}
  461. {*  for <Dly> milliseconds between each character.  Useful for systems that *}
  462. {*  cannot keep up with transmissions sent at full speed.                   *}
  463. {*                                                                          *}
  464. {****************************************************************************}
  465.  
  466. Procedure ComWriteWithDelay(ComPort:C_ports; St:String; Dly:Word); Export;
  467.  
  468. Var
  469.   X   : Byte;
  470.  
  471. Begin
  472.   If (ComPort IN [1..C_MaxCom]) And
  473.      (portopen[ComPort])
  474.     Then
  475.       Begin
  476.         ComWaitForClear(ComPort);
  477.         For X := 1 To Length(St) Do
  478.           Begin
  479.             ComWriteChW(ComPort,St[X]);
  480.             ComWaitForClear(ComPort);
  481.             Delay(dly);
  482.           End;
  483.       End;
  484. End; {of ComWriteWithDelay}
  485.  
  486. {****************************************************************************}
  487. {*                                                                          *}
  488. {* Procedure ComReadln(ComPort:Byte; Var St:String; Size:Byte; Echo:Boolean)*}
  489. {*                                                                          *}
  490. {*  ComPort:Byte  ->  Port # to use (1 - C_MaxCom).                         *}
  491. {*                    Exits immediately if out of range or port unopened.   *}
  492. {*  St:String     <-  Edited string from remote                             *}
  493. {*  Size:Byte;    ->  Maximum allowable length of input                     *}
  494. {*  Echo:Boolean; ->  Set TRUE to echo received characters                  *}
  495. {*                                                                          *}
  496. {*  ComReadln is the remote equivalent of the standard Pascal READLN pro-   *}
  497. {*  cedure with some enhancements.  ComReadln will accept an entry of up to *}
  498. {*  40 printable ASCII characters, supporting ^H and ^X editing commands.   *}
  499. {*  Echo-back of the entry (for full-duplex operation) is optional.  All    *}
  500. {*  control characters, as well as non-ASCII (8th bit set) characters are   *}
  501. {*  stripped.  If <Echo> is enabled, ASCII BEL (^G) characters are sent     *}
  502. {*  when erroneous characters are intercepted.  Upon receipt of a ^M (CR),  *}
  503. {*  the procedure is terminated and the final string result returned.       *}
  504. {*                                                                          *}
  505. {****************************************************************************}
  506.  
  507. Procedure ComReadln(ComPort:C_ports; Var St:String; Size:Byte; Echo:Boolean); Export;
  508.  
  509. Var
  510.   Len,X : Byte;
  511.   Ch    : Char;
  512.   Done  : Boolean;
  513.  
  514. Begin
  515.   St:='';
  516.   If (ComPort IN [1..C_MaxCom]) And
  517.      (portopen[ComPort])
  518.     Then
  519.       Begin
  520.         Done := False;
  521.         Repeat
  522.           Len:=Length(St);
  523.           Ch :=Chr(Ord(ComReadChW(ComPort)) And $7F);
  524.  
  525.           Case Ch Of
  526.             ^H : If Len>0
  527.                   Then
  528.                     Begin
  529.                       Dec(Len);
  530.                       St[0]:=Chr(Len);
  531.                       If Echo Then ComWrite(ComPort,#8#32#8);
  532.                     End
  533.                   Else ComWriteChW(ComPort,^G);
  534.             ^J : If eolns[comport]=C_lf
  535.                    Then
  536.                      Begin
  537.                        Done:=True;
  538.                        If Echo Then ComWrite(ComPort,#13#10);
  539.                      End;
  540.             ^M : If eolns[comport]=C_cr
  541.                    Then
  542.                      Begin
  543.                        Done:=True;
  544.                        If Echo Then ComWrite(ComPort,#13#10);
  545.                      End;
  546.             ^X : Begin
  547.                    St:='';
  548.                    If Len=0 Then ComWriteCh(ComPort,^G);
  549.                    If Echo
  550.                      Then
  551.                        For X:=1 to Len Do
  552.                          ComWrite(ComPort,#8#32#8);
  553.                  End;
  554.           #32..
  555.           #127 : If Len<Size
  556.                    Then
  557.                      Begin
  558.                        Inc(Len);
  559.                        St[Len]:=Ch;
  560.                        St[0]:=Chr(Len);
  561.                        If Echo Then ComWriteChW(ComPort,Ch);
  562.                      End
  563.                    Else
  564.                      If Echo Then ComWriteChW(ComPort,^G);
  565.           Else
  566.             If Echo Then ComWriteChW(ComPort,^G)
  567.           End;
  568.         Until Done;
  569.       End;
  570. End; {of ComReadln}
  571.  
  572. {****************************************************************************}
  573. {*                                                                          *}
  574. {*  Procedure SetRTSMode(ComPort:Byte; Mode:Boolean; RTSOn,RTSOff:Word)     *}
  575. {*                                                                          *}
  576. {*  ComPort:Byte  ->  Port # to use (1 - C_MaxCom).                         *}
  577. {*                    Request ignored if out of range or unopened.          *}
  578. {*  Mode:Boolean  ->  TRUE to enable automatic RTS handshake                *}
  579. {*  RTSOn:Word    ->  Buffer-usage point at which the RTS line is asserted  *}
  580. {*  RTSOff:Word   ->  Buffer-usage point at which the RTS line is dropped   *}
  581. {*                                                                          *}
  582. {*  SetRTSMode enables or disables automated RTS handshaking.  If [MODE] is *}
  583. {*  TRUE, automated RTS handshaking is enabled.  If enabled, the RTS line   *}
  584. {*  will be DROPPED when the # of buffer bytes used reaches or exceeds that *}
  585. {*  of [RTSOff].  The RTS line will then be re-asserted when the buffer is  *}
  586. {*  emptied down to the [RTSOn] usage point.  If either [RTSOn] or [RTSOff] *}
  587. {*  exceeds the input buffer size, they will be forced to (buffersize-1).   *}
  588. {*  If [RTSOn] > [RTSOff] then [RTSOn] will be the same as [RTSOff].        *}
  589. {*  The actual handshaking control is located in the interrupt driver for   *}
  590. {*  the port (see ASYNC12.ASM).                                             *}
  591. {*                                                                          *}
  592. {****************************************************************************}
  593.  
  594. Procedure SetRTSmode(ComPort:C_ports; Mode:Boolean; RTSOn,RTSOff:Word); Export;
  595.  
  596. Var
  597.   dcb : tdcb;
  598.   cid : Integer;
  599.  
  600. Begin
  601.   If (ComPort IN [1..C_MaxCom]) And
  602.      (portopen[ComPort])
  603.     Then
  604.       Begin
  605.         cid:=cids[comport];
  606.  
  607.         If GetCommState(cid,dcb)=0
  608.           Then
  609.             Begin
  610.               With dcb Do
  611.                 Case mode of
  612.                   True  : Begin
  613.                             fRTSflow:=fon;
  614.                             Xonlim  :=inbs[comport]-RTSon ;
  615.                             Xofflim :=inbs[comport]-RTSoff;
  616.                           End;
  617.                   False : Begin
  618.                             fRTSflow:=foff;
  619.                           End;
  620.                 End;
  621.               SetCommState(dcb);
  622.             End;
  623.       End;
  624. End; {of SetRTSmode}
  625.  
  626. {****************************************************************************}
  627. {*                                                                          *}
  628. {*  Procedure SetCTSMode(ComPort:Byte; Mode:Boolean)                        *}
  629. {*                                                                          *}
  630. {*  ComPort:Byte  ->  Port # to use (1 - C_MaxCom).                         *}
  631. {*                    Request ignored if out of range or unopened.          *}
  632. {*  Mode:Boolean  ->  Set to TRUE to enable automatic CTS handshake.        *}
  633. {*                                                                          *}
  634. {*  SetCTSMode allows the enabling or disabling of automated CTS handshak-  *}
  635. {*  ing.  If [Mode] is TRUE, CTS handshaking is enabled, which means that   *}
  636. {*  if the remote drops the CTS line, the transmitter will be disabled      *}
  637. {*  until the CTS line is asserted again.  Automatic handshake is disabled  *}
  638. {*  if [Mode] is FALSE.  CTS handshaking and "software" handshaking (pro-   *}
  639. {*  vided by the SoftHandshake procedure) ARE compatable and may be used    *}
  640. {*  in any combination.                                                     *}
  641. {*                                                                          *}
  642. {****************************************************************************}
  643.  
  644. Procedure SetCTSMode(ComPort:Byte; Mode:Boolean); Export;
  645.  
  646. Var
  647.   dcb : tdcb;
  648.   cid : Integer;
  649.  
  650. Begin
  651.   If (ComPort IN [1..C_MaxCom]) And
  652.      (portopen[ComPort])
  653.     Then
  654.       Begin
  655.         cid:=cids[comport];
  656.  
  657.         If GetCommState(cid,dcb)=0
  658.           Then
  659.             Begin
  660.               Case mode of
  661.                 True  : foutxCTSflow:=fon;
  662.                 False : foutxCTSflow:=foff;
  663.               End;
  664.               SetCommState(dcb);
  665.             End;
  666.       End;
  667. End; {of SetCTSmode}
  668.  
  669. {****************************************************************************}
  670. {*                                                                          *}
  671. {*  Procedure SoftHandshake(ComPort:Byte; Mode:Boolean; Start,Stop:Char)    *}
  672. {*                                                                          *}
  673. {*  ComPort:Byte  ->  Port # to use (1 - C_MaxCom).                         *}
  674. {*                    Request ignored if out of range or unopened.          *}
  675. {*  Mode:Boolean  ->  Set to TRUE to enable transmit software handshake     *}
  676. {*  Start:Char    ->  START control character (usually ^Q)                  *}
  677. {*                    Defaults to ^Q if character passed is >= <Space>      *}
  678. {*  Stop:Char     ->  STOP control character (usually ^S)                   *}
  679. {*                    Defaults to ^S if character passed is >= <Space>      *}
  680. {*                                                                          *}
  681. {*  SoftHandshake controls the usage of "Software" (control-character)      *}
  682. {*  handshaking on transmission.  If "software handshake" is enabled        *}
  683. {*  ([Mode] is TRUE), transmission will be halted if the character in       *}
  684. {*  [Stop] is received.  Transmission is re-enabled if the [Start] char-    *}
  685. {*  acter is received.  Both the [Start] and [Stop] characters MUST be      *}
  686. {*  CONTROL characters (i.e. Ord(Start) and Ord(Stop) must both be < 32).   *}
  687. {*  Also, <Start> and <Stop> CANNOT be the same character.  If either one   *}
  688. {*  of these restrictions are violated, the defaults (^Q for <Start> and ^S *}
  689. {*  for <Stop>) will be used.                                               *}
  690. {*                                                                          *}
  691. {****************************************************************************}
  692.  
  693. Procedure SoftHandshake(ComPort:Byte; Mode:Boolean; Start,Stop:Char); Export;
  694.  
  695. Var
  696.   dcb : tdcb;
  697.   cid : integer;
  698.  
  699. Begin
  700.   If (ComPort IN [1..C_MaxCom]) And
  701.      (portopen[ComPort])
  702.     Then
  703.       Begin
  704.         cid:=cids[comport];
  705.  
  706.         If GetCommState(cid,dcb)=0
  707.           Then
  708.             Begin
  709.               Case mode of
  710.                 True  : Begin
  711.                           foutx:=fon;
  712.                           If (start IN [#00..#31]) And (start<>stop)
  713.                             Then dcb.Xonchar:=start
  714.                             Else dcb.Xonchar:=^Q;
  715.                           If (stop  IN [#00..#31]) And (start<>stop)
  716.                             Then dcb.Xoffchar:=stop
  717.                             Else dcb.Xoffchar:=^S;
  718.                         End;
  719.                 False : foutx:=foff;
  720.               End;
  721.               SetCommState(dcb);
  722.             End;
  723.       End;
  724. End; {of Softhandshake}
  725.  
  726. {****************************************************************************}
  727. {*                                                                          *}
  728. {*  Function ComExist(ComPort:Byte) : Boolean                               *}
  729. {*                                                                          *}
  730. {*  ComPort:Byte  ->  Port # to use (1 - C_MaxCom)                          *}
  731. {*                    Returns FALSE if out of range                         *}
  732. {*  Returns TRUE if hardware for selected port is detected & tests OK       *}
  733. {*                                                                          *}
  734. {****************************************************************************}
  735.  
  736. Function ComExist(ComPort:C_ports) : Boolean; Export;
  737.  
  738. VAR
  739.   mode : String;
  740.   dcb  : tdcb;
  741.  
  742. Begin
  743.   If (ComPort IN [1..C_MaxCom])
  744.     Then
  745.       Begin
  746.         mode:='COM'+Chr(Comport+Ord('0'))+' 19200,N,8,1'#0;
  747.         ComExist:=(BuildCommDCB(@mode[1],dcb)=0);
  748.       End
  749.     Else ComExist:=false;
  750. End; {of Comexist}
  751.  
  752. {****************************************************************************}
  753. {*                                                                          *}
  754. {*  Function ComTrueBaud(Baud:Longint) : Real                               *}
  755. {*                                                                          *}
  756. {*  Baud:Longint  ->  User baud rate to test.                               *}
  757. {*                    Should be between C_MinBaud and C_MaxBaud.            *}
  758. {*  Returns the actual baud rate based on the accuracy of the 8250 divider. *}
  759. {*                                                                          *}
  760. {*  The ASYNC12 communications package allows the programmer to select ANY  *}
  761. {*  baud rate, not just those that are predefined by the BIOS or other      *}
  762. {*  agency.  Since the 8250 uses a divider/counter chain to generate it's   *}
  763. {*  baud clock, many non-standard baud rates can be generated.  However,    *}
  764. {*  the binary counter/divider is not always capable of generating the      *}
  765. {*  EXACT baud rate desired by a user.  This function, when passed a valid  *}
  766. {*  baud rate, will return the ACTUAL baud rate that will be generated.     *}
  767. {*  The baud rate is based on a 8250 input clock rate of 1.73728 MHz.       *}
  768. {*                                                                          *}
  769. {****************************************************************************}
  770.  
  771. Function ComTrueBaud(Baud:Longint) : Real; Export;
  772.  
  773. Var
  774.   X : Real;
  775.   Y : Word;
  776.  
  777. Begin
  778.   X := Baud;
  779.   If X < C_MinBaud Then X := C_MinBaud;
  780.   If X > C_MaxBaud Then X := C_MaxBaud;
  781.   ComTrueBaud := C_MaxBaud / Round($900/(X/50));
  782. End; {of ComTrueBaud}
  783.  
  784. {****************************************************************************}
  785. {*                                                                          *}
  786. {* Function Lstr(l : Longint) : String;                                     *}
  787. {*                                                                          *}
  788. {* l:Longint       ->  Number converted to a string                         *}
  789. {*                                                                          *}
  790. {* This function converts longint l to a string.                            *}
  791. {*                                                                          *}
  792. {****************************************************************************}
  793.  
  794. Function Lstr(l : Longint) : String;
  795.  
  796. Var
  797.   s : String;
  798.  
  799. Begin
  800.   Str(l:0,s);
  801.   Lstr:=s;
  802. End; {of Lstr}
  803.  
  804. {****************************************************************************}
  805. {*                                                                          *}
  806. {*  Procedure ComParams(ComPort:Byte; Baud:Longint;                         *}
  807. {*                      WordSize:Byte; Parity:Char; StopBits:Byte);         *}
  808. {*                                                                          *}
  809. {*  ComPort:Byte   ->  Port # to initialize.  Must be (1 - C_MaxCom)        *}
  810. {*                     Procedure aborted if port # invalid or unopened.     *}
  811. {*  Baud:Longint   ->  Desired baud rate.  Should be (C_MinBaud - C_MaxBaud)*}
  812. {*                     C_MinBaud or C_MaxBaud used if out of range.         *}
  813. {*  WordSize:Byte  ->  Word size, in bits.  Must be 5 - 8 bits.             *}
  814. {*                     8-bit word used if out of range.                     *}
  815. {*  Parity:Char    ->  Parity classification.                               *}
  816. {*                     May be N)one, E)ven, O)dd, M)ark or S)pace.          *}
  817. {*                     N)one selected if classification unknown.            *}
  818. {*  StopBits:Byte  ->  # of stop bits to pad character with.  Range (1-2)   *}
  819. {*                     1 stop bit used if out of range.                     *}
  820. {*                                                                          *}
  821. {*  ComParams is used to configure an OPEN'ed port for the desired comm-    *}
  822. {*  unications parameters, namely baud rate, word size, parity form and     *}
  823. {*  # of stop bits.  A call to this procedure will set up the port approp-  *}
  824. {*  riately, as well as assert the DTR, RTS and OUT2 control lines and      *}
  825. {*  clear all buffers.                                                      *}
  826. {*                                                                          *}
  827. {****************************************************************************}
  828.  
  829. Procedure ComParams(ComPort:C_ports; Baud:LongInt; WordSize:Byte; Parity:Char; StopBits:Byte); Export;
  830.  
  831. Var
  832.   mode : String;
  833.   cid  : Integer;
  834.   dcb  : tdcb;
  835.  
  836. Begin
  837.   If (ComPort IN [1..C_MaxCom]) And
  838.      (portopen[ComPort])
  839.     Then
  840.       Begin
  841.         cid:=cids[comport];
  842.  
  843.       {----Like COM1 9600,N,8,1}
  844.         mode:='COM'+Chr(Comport+Ord('0'))+' '+Lstr(baud)+','+Upcase(Parity)+','+Lstr(Wordsize)+','+Lstr(stopbits)+#0;
  845.         IF (BuildCommDCB(@mode[1],dcb)=0)
  846.           Then
  847.             Begin
  848.               dcb.id:=cid;
  849.               SetCommState(dcb);
  850.             End;
  851.       End;
  852. End; {of ComParams}
  853.  
  854. {****************************************************************************}
  855. {*                                                                          *}
  856. {*  Function OpenCom(ComPort:Byte; InBufferSize,OutBufferSize:Word):Boolean *}
  857. {*                                                                          *}
  858. {*  ComPort:Byte        ->  Port # to OPEN (1 - C_MaxCom)                   *}
  859. {*                          Request will fail if out of range or port OPEN  *}
  860. {*  InBufferSize:Word   ->  Requested size of input (receive) buffer        *}
  861. {*  OutBufferSize:Word  ->  Requested size of output (transmit) buffer      *}
  862. {*  Returns success/fail status of OPEN request (TRUE if OPEN successful)   *}
  863. {*                                                                          *}
  864. {*  OpenCom must be called before any activity (other than existence check, *}
  865. {*  see the ComExist function) takes place.  OpenCom initializes the        *}
  866. {*  interrupt drivers and serial communications hardware for the selected   *}
  867. {*  port, preparing it for I/O. Once a port has been OPENed, a call to      *}
  868. {*  ComParams should be made to set up communications parameters (baud rate,*}
  869. {*  parity and the like).  Once this is done, I/O can take place on the     *}
  870. {*  port. OpenCom will return a TRUE value if the opening procedure was     *}
  871. {*  successful, or FALSE if it is not.                                      *}
  872. {*                                                                          *}
  873. {****************************************************************************}
  874.  
  875. Function OpenCom(ComPort:C_ports; InBufferSize,OutBufferSize:Word) : Boolean; Export;
  876.  
  877. Var
  878.   cid  : Integer;
  879.   comp : String;
  880.  
  881. Begin
  882.   OpenCom := False;
  883.   If    (ComPort IN [1..C_MaxCom]) And
  884.      Not(portopen[ComPort])      And
  885.          ComExist(comport)
  886.     Then
  887.       Begin
  888.         comp:='COM'+Chr(comport+Ord('0'))+#0;
  889.         cid:=OpenComm(@comp[1],InBufferSize,OutBufferSize);
  890.         If (cid>=0)
  891.           Then
  892.             Begin
  893.               cids [comport]     :=cid;
  894.               inbs [comport]     :=InBufferSize;
  895.               outbs[comport]     :=OutBufferSize;
  896.               portopen[comport]:=true;
  897.             End;
  898.         OpenCom:=(cid>=0);
  899.       End;
  900. End; {of OpenCom}
  901.  
  902. {****************************************************************************}
  903. {*                                                                          *}
  904. {*  Procedure CloseCom(ComPort:Byte)                                        *}
  905. {*                                                                          *}
  906. {*  ComPort:Byte  ->  Port # to close                                       *}
  907. {*                    Request ignored if port closed or out of range.       *}
  908. {*                                                                          *}
  909. {*  CloseCom will un-link the interrupt drivers for a port, deallocate it's *}
  910. {*  buffers and drop the DTR and RTS signal lines for a port opened with    *}
  911. {*  the OpenCom function.  It should be called before exiting your program  *}
  912. {*  to ensure that the port is properly shut down.                          *}
  913. {*  NOTE:  CloseCom shuts down a communications channel IMMEDIATELY,        *}
  914. {*         even if there is data present in the input or output buffers.    *}
  915. {*         Therefore, you may wish to call the ComWaitForClear procedure    *}
  916. {*         before closing the ports.                                        *}
  917. {*                                                                          *}
  918. {****************************************************************************}
  919.  
  920. Procedure CloseCom(ComPort:C_ports); Export;
  921.  
  922. Var
  923.   cid : integer;
  924.  
  925. Begin
  926.   If (ComPort IN [1..C_MaxCom]) And
  927.      (portopen[ComPort])
  928.     Then
  929.       Begin
  930.         cid:=cids[comport];
  931.         portopen[comport]:=Not(CloseComm(cid)=0);
  932.       End;
  933. End; {of CloseCom}
  934.  
  935. {****************************************************************************}
  936. {*                                                                          *}
  937. {*  Procedure CloseAllComs                                                  *}
  938. {*                                                                          *}
  939. {*  CloseAllComs will CLOSE all currently OPENed ports.  See the CloseCom   *}
  940. {*  procedure description for more details.                                 *}
  941. {*                                                                          *}
  942. {****************************************************************************}
  943.  
  944. Procedure CloseAllComs; Export;
  945.  
  946. Var
  947.   X : C_ports;
  948.  
  949. Begin
  950.   For X := 1 To C_MaxCom Do
  951.     If portopen[X] Then CloseCom(X);
  952. End; {of CloseAllComs}
  953.  
  954. {****************************************************************************}
  955. {*                                                                          *}
  956. {*  Procedure ComSetEoln(ComPort:C_ports;EolnCh : T_eoln)                 *}
  957. {*                                                                          *}
  958. {*  ComPort:Byte  ->  Port # for which to alter the eoln character          *}
  959. {*                    Request ignored if port closed or out of range.       *}
  960. {*  EolnCh:T_eoln ->  Eoln character needed                                 *}
  961. {*                                                                          *}
  962. {*  With this function one can toggle the eoln character between cr and lf. *}
  963. {*                                                                          *}
  964. {****************************************************************************}
  965.  
  966. Procedure ComSetEoln(ComPort:C_ports;EolnCh : T_eoln); Export;
  967.  
  968. Begin
  969.   If (ComPort IN [1..C_MaxCom]) And
  970.      (portopen[ComPort])
  971.     Then eolns[comport]:=EolnCh;
  972. End; {of ComSetEoln}
  973.  
  974. {****************************************************************************}
  975. {*                                                                          *}
  976. {*  Function  ComGetBufsize(ComPort:C_ports;IO : char)                      *}
  977. {*                                                                          *}
  978. {*  ComPort:Byte  ->  Port # for which to retrieve the buffersize           *}
  979. {*                    Request ignored if port closed or out of range.       *}
  980. {*  IO:Char       ->  Action code; I=Input, O=Output                        *}
  981. {*                    Returns 0 if action code unrecognized.                *}
  982. {*                                                                          *}
  983. {*  This function will return the buffer size defined for a serial port.    *}
  984. {*                                                                          *}
  985. {****************************************************************************}
  986.  
  987. Function ComGetBufsize(ComPort:C_ports;IO : Char) : WORD; Export;
  988.  
  989. Begin
  990.   ComGetBufSize:=0;
  991.   If (ComPort IN [1..C_MaxCom]) And
  992.      (portopen[ComPort])
  993.     Then
  994.       CASE Upcase(IO) OF
  995.         'I' : ComgetBufSize:=inbs [comport];
  996.         'O' : ComgetBufSize:=outbs[comport];
  997.       END;
  998. End; {of ComGetBufferSize}
  999.  
  1000. {****************************************************************************}
  1001.  
  1002. Exports
  1003.   ComReadCh         index  1,
  1004.   ComReadChW        index  2,
  1005.   ComWriteCh        index  3,
  1006.   ComWriteChW       index  4,
  1007.   ClearCom          index  5,
  1008.   ComBufferLeft     index  6,
  1009.   ComWaitForClear   index  7,
  1010.   ComWrite          index  8,
  1011.   ComWriteln        index  9,
  1012.   ComWriteWithDelay index 10,
  1013.   ComReadln         index 11,
  1014.   SetRTSmode        index 12,
  1015.   SetCTSMode        index 13,
  1016.   SoftHandshake     index 14,
  1017.   ComExist          index 15,
  1018.   ComTrueBaud       index 16,
  1019.   ComParams         index 17,
  1020.   OpenCom           index 18,
  1021.   CloseCom          index 19,
  1022.   CloseAllComs      index 20,
  1023.   ComSetEoln        index 21,
  1024.   ComGetBufSize     index 22;
  1025.  
  1026. Begin
  1027. End.
  1028.  
  1029. {----The following procedures/functions from the async12 }
  1030. {    package are not available                           }
  1031.  
  1032. {****************************************************************************}
  1033. {*                                                                          *}
  1034. {*  Procedure SetDTR(ComPort:Byte; Assert:Boolean);                         *}
  1035. {*                                                                          *}
  1036. {*  ComPort:Byte    ->  Port # to use (1 - C_MaxCom)                        *}
  1037. {*                      Call ignored if out-of-range                        *}
  1038. {*  Assert:Boolean  ->  DTR assertion flag (TRUE to assert DTR)             *}
  1039. {*                                                                          *}
  1040. {*  Provides a means to control the port's DTR (Data Terminal Ready) signal *}
  1041. {*  line.  When [Assert] is TRUE, the DTR line is placed in the "active"    *}
  1042. {*  state, signalling to a remote system that the host is "on-line"         *}
  1043. {*  (although not nessesarily ready to receive data - see SetRTS).          *}
  1044. {*                                                                          *}
  1045. {****************************************************************************}
  1046.  
  1047. Procedure SetDTR(ComPort:Byte; Assert:Boolean);
  1048.  
  1049. Begin
  1050. End; {of SetDTR}
  1051.  
  1052. {****************************************************************************}
  1053. {*                                                                          *}
  1054. {*  Procedure SetRTS(ComPort:Byte; Assert:Boolean)                          *}
  1055. {*                                                                          *}
  1056. {*  ComPort:Byte    ->  Port # to use (1 - C_MaxCom)                        *}
  1057. {*                      Call ignored if out-of-range                        *}
  1058. {*  Assert:Boolean  ->  RTS assertion flag (Set TRUE to assert RTS)         *}
  1059. {*                                                                          *}
  1060. {*  SetRTS allows a program to manually control the Request-To-Send (RTS)   *}
  1061. {*  signal line.  If RTS handshaking is disabled (see C_Ctrl definition     *}
  1062. {*  and the the SetRTSMode procedure), this procedure may be used.  SetRTS  *}
  1063. {*  should NOT be used if RTS handshaking is enabled.                       *}
  1064. {*                                                                          *}
  1065. {****************************************************************************}
  1066.  
  1067. Procedure SetRTS(ComPort:Byte; Assert:Boolean);
  1068.  
  1069. Begin
  1070. End; {of SetRTS}
  1071.  
  1072. {****************************************************************************}
  1073. {*                                                                          *}
  1074. {*  Procedure SetOUT1(ComPort:Byte; Assert:Boolean)                         *}
  1075. {*                                                                          *}
  1076. {*  ComPort:Byte    ->  Port # to use (1 - C_MaxCom)                        *}
  1077. {*                      Call ignored if out-of-range                        *}
  1078. {*  Assert:Boolean  ->  OUT1 assertion flag (set TRUE to assert OUT1 line)  *}
  1079. {*                                                                          *}
  1080. {*  SetOUT1 is provided for reasons of completeness only, since the         *}
  1081. {*  standard PC/XT/AT configurations do not utilize this control signal.    *}
  1082. {*  If [Assert] is TRUE, the OUT1 signal line on the 8250 will be set to a  *}
  1083. {*  LOW logic level (inverted logic).  The OUT1 signal is present on pin 34 *}
  1084. {*  of the 8250 (but not on the port itself).                               *}
  1085. {*                                                                          *}
  1086. {****************************************************************************}
  1087.  
  1088. Procedure SetOUT1(ComPort:Byte; Assert:Boolean);
  1089.  
  1090. Begin
  1091. End;  {of SetOUT1}
  1092.  
  1093. {****************************************************************************}
  1094. {*                                                                          *}
  1095. {*  Procedure SetOUT2(ComPort:Byte; Assert:Boolean)                         *}
  1096. {*                                                                          *}
  1097. {*  ComPort:Byte    ->  Port # to use (1 - C_MaxCom)                        *}
  1098. {*                      Call ignored if out-of-range                        *}
  1099. {*  Assert:Boolean  ->  OUT2 assertion flag (set TRUE to assert OUT2 line)  *}
  1100. {*                                                                          *}
  1101. {*  The OUT2 signal line, although not available on the port itself, is     *}
  1102. {*  used to gate the 8250 <INTRPT> (interrupt) line and thus acts as a      *}
  1103. {*  redundant means of controlling 8250 interrupts.  When [Assert] is TRUE, *}
  1104. {*  the /OUT2 line on the 8250 is lowered, which allows the passage of the  *}
  1105. {*  <INTRPT> signal through a gating arrangement, allowing the 8250 to      *}
  1106. {*  generate interrupts.  Int's can be disabled bu unASSERTing this line.   *}
  1107. {*                                                                          *}
  1108. {****************************************************************************}
  1109.  
  1110. Procedure SetOUT2(ComPort:Byte; Assert:Boolean);
  1111.  
  1112. Begin
  1113. End; {of SetOUT2}
  1114.  
  1115. {****************************************************************************}
  1116. {*                                                                          *}
  1117. {*  Function CTSStat(ComPort:Byte) : Boolean                                *}
  1118. {*                                                                          *}
  1119. {*  ComPort:Byte  ->  Port # to use (1 - C_MaxCom)                          *}
  1120. {*                    Call ignored if out-of-range                          *}
  1121. {*  Returns status of Clear-To-Send line (TRUE if CTS asserted)             *}
  1122. {*                                                                          *}
  1123. {*  CTSStat provides a means to interrogate the Clear-To-Send hardware      *}
  1124. {*  handshaking line.  In a typical arrangement, when CTS is asserted, this *}
  1125. {*  signals the host (this computer) that the receiver is ready to accept   *}
  1126. {*  data (in contrast to the DSR line, which signals the receiver as        *}
  1127. {*  on-line but not nessesarily ready to accept data).  An automated mech-  *}
  1128. {*  ansim (see CTSMode) is provided to do this, but in cases where this is  *}
  1129. {*  undesirable or inappropriate, the CTSStat function can be used to int-  *}
  1130. {*  terrogate this line manually.                                           *}
  1131. {*                                                                          *}
  1132. {****************************************************************************}
  1133.  
  1134. Function CTSStat(ComPort:Byte) : Boolean;
  1135.  
  1136. Begin
  1137. End; {of CTSstat}
  1138.  
  1139. {****************************************************************************}
  1140. {*                                                                          *}
  1141. {*  Function DSRStat(ComPort:Byte) : Boolean                                *}
  1142. {*                                                                          *}
  1143. {*  ComPort:Byte  ->  Port # to use (1 - C_MaxCom)                          *}
  1144. {*                    Call ignored if out-of-range                          *}
  1145. {*  Returns status of Data Set Ready (DSR) signal line.                     *}
  1146. {*                                                                          *}
  1147. {*  The Data Set Ready (DSR) line is typically used by a remote station     *}
  1148. {*  to signal the host system that it is on-line (although not nessesarily  *}
  1149. {*  ready to receive data yet - see CTSStat).  A remote station has the DSR *}
  1150. {*  line asserted if DSRStat returns TRUE.                                  *}
  1151. {*                                                                          *}
  1152. {****************************************************************************}
  1153.  
  1154. Function DSRStat(ComPort:Byte) : Boolean;
  1155.  
  1156. Begin
  1157. End; {of DSRstat}
  1158.  
  1159. {****************************************************************************}
  1160. {*                                                                          *}
  1161. {*  Function RIStat(ComPort:Byte) : Boolean                                 *}
  1162. {*                                                                          *}
  1163. {*  ComPort:Byte  ->  Port # to use (1 - C_MaxCom)                          *}
  1164. {*                    Call ignored if out-of-range                          *}
  1165. {*                                                                          *}
  1166. {*  Returns the status of the Ring Indicator (RI) line.  This line is       *}
  1167. {*  typically used only by modems, and indicates that the modem has detect- *}
  1168. {*  ed an incoming call if RIStat returns TRUE.                             *}
  1169. {*                                                                          *}
  1170. {****************************************************************************}
  1171.  
  1172. Function RIStat(ComPort:Byte) : Boolean;
  1173.  
  1174. Begin
  1175. End; {of RIstat}
  1176.  
  1177. {****************************************************************************}
  1178. {*                                                                          *}
  1179. {*  Function DCDStat(ComPort:Byte) : Boolean                                *}
  1180. {*                                                                          *}
  1181. {*  ComPort:Byte  ->  Port # to use (1 - C_MaxCom)                          *}
  1182. {*                    Call ignored if out-of-range                          *}
  1183. {*                                                                          *}
  1184. {*  Returns the status of the Data Carrier Detect (DCD) line from the rem-  *}
  1185. {*  ote device, typically a modem.  When asserted (DCDStat returns TRUE),   *}
  1186. {*  the modem indicates that it has successfuly linked with another modem   *}
  1187. {*  device at another site.                                                 *}
  1188. {*                                                                          *}
  1189. {****************************************************************************}
  1190.  
  1191. Function DCDStat(ComPort:Byte) : Boolean;
  1192.  
  1193. Begin
  1194. End; {of DCDstat}
  1195.  
  1196. { ---------------    WINDOWS INTERFACE UNIT -------------------- }
  1197.  
  1198. Unit WinAsync;
  1199.  
  1200. Interface
  1201.  
  1202. CONST
  1203.   C_MaxCom   = 4;             {----supports COM1..COM4                        }
  1204.   C_MinBaud  = 110;           {----min baudrate supported by windows 3.1      }
  1205.   C_MaxBaud  = 256000;        {----max baudrate supported by windows 3.1      }
  1206.  
  1207. TYPE
  1208.   T_eoln     = (C_cr,C_lf);   {----used to change EOLN character from cr to lf}
  1209.   C_ports    = 1..C_MaxCom;   {----subrange type to minimize programming errors}
  1210.  
  1211.  
  1212. Function  ComReadCh(comport:C_ports)  : Char;
  1213. Function  ComReadChW(comport:C_ports) : Char;
  1214. Procedure ComReadln(ComPort:C_ports; Var St:String; Size:Byte; Echo:Boolean);
  1215.  
  1216. Procedure ComWriteCh(comport:C_ports; Ch:Char);
  1217. Procedure ComWriteChW(comport:C_ports; Ch:Char);
  1218. Procedure ComWrite(ComPort:C_ports; St:String);
  1219. Procedure ComWriteln(ComPort:C_ports; St:String);
  1220. Procedure ComWriteWithDelay(ComPort:C_ports; St:String; Dly:Word);
  1221.  
  1222. Procedure ClearCom(ComPort:C_Ports;IO:Char);
  1223. Function  ComBufferLeft(ComPort:C_ports; IO:Char) : Word;
  1224. Procedure ComWaitForClear(ComPort:C_ports);
  1225.  
  1226. Procedure SetRTSmode(ComPort:C_ports; Mode:Boolean; RTSOn,RTSOff:Word);
  1227. Procedure SetCTSMode(ComPort:Byte; Mode:Boolean);
  1228. Procedure SoftHandshake(ComPort:Byte; Mode:Boolean; Start,Stop:Char);
  1229.  
  1230. Function  ComExist(ComPort:C_ports) : Boolean;
  1231. Procedure ComParams(ComPort:C_ports; Baud:LongInt; WordSize:Byte; Parity:Char; StopBits:Byte);
  1232. Function  ComTrueBaud(Baud:Longint) : Real;
  1233. Function  OpenCom(ComPort:C_ports; InBufferSize,OutBufferSize:Word) : Boolean;
  1234.  
  1235. Procedure CloseCom(ComPort:C_ports);
  1236. Procedure CloseAllComs;
  1237. Procedure ComSetEoln(ComPort:C_ports;EolnCh : T_eoln);
  1238.  
  1239. Function ComGetBufsize(ComPort:C_ports;IO : Char) : WORD;
  1240.  
  1241. Implementation
  1242.  
  1243. Function  ComReadCh(comport:C_ports)  : Char;                                  external 'async12w';
  1244. Function  ComReadChW(comport:C_ports) : Char;                                  external 'async12w';
  1245. Procedure ComWriteCh(comport:C_ports; Ch:Char);                                external 'async12w';
  1246. Procedure ComWriteChW(comport:C_ports; Ch:Char);                               external 'async12w';
  1247. Procedure ClearCom(ComPort:C_Ports;IO:Char);                                   external 'async12w';
  1248. Function  ComBufferLeft(ComPort:C_ports; IO:Char) : Word;                      external 'async12w';
  1249. Procedure ComWaitForClear(ComPort:C_ports);                                    external 'async12w';
  1250. Procedure ComWrite(ComPort:C_ports; St:String);                                external 'async12w';
  1251. Procedure ComWriteln(ComPort:C_ports; St:String);                              external 'async12w';
  1252. Procedure ComWriteWithDelay(ComPort:C_ports; St:String; Dly:Word);             external 'async12w';
  1253. Procedure ComReadln(ComPort:C_ports; Var St:String;Size:Byte; Echo:Boolean);   external 'async12w';
  1254. Procedure SetRTSmode(ComPort:C_ports; Mode:Boolean; RTSOn,RTSOff:Word);        external 'async12w';
  1255. Procedure SetCTSMode(ComPort:Byte; Mode:Boolean);                              external 'async12w';
  1256. Procedure SoftHandshake(ComPort:Byte; Mode:Boolean; Start,Stop:Char);          external 'async12w';
  1257. Function  ComExist(ComPort:C_ports) : Boolean;                                 external 'async12w';
  1258. Function  ComTrueBaud(Baud:Longint) : Real;                                    external 'async12w';
  1259. Procedure ComParams(ComPort:C_ports; Baud:LongInt; WordSize:Byte;
  1260.                                      Parity:Char; StopBits:Byte);              external 'async12w';
  1261. Function  OpenCom(ComPort:C_ports; InBufferSize,OutBufferSize:Word) : Boolean; external 'async12w';
  1262. Procedure CloseCom(ComPort:C_ports);                                           external 'async12w';
  1263. Procedure CloseAllComs;                                                        external 'async12w';
  1264. Procedure ComSetEoln(ComPort:C_ports;EolnCh : T_eoln);                         external 'async12w';
  1265.  
  1266. Function ComGetBufsize(ComPort:C_ports;IO : Char) : WORD;                      external 'async12w';
  1267.  
  1268.  
  1269. End.
  1270.  
  1271. { ------------------------------   TEST PROGRAM  ----------------------- }
  1272.  
  1273. Program Asynctst;
  1274.  
  1275. Uses
  1276.   Wincrt,
  1277.   Asyncwin;
  1278.  
  1279. {----Demo main program for Async12w}
  1280.  
  1281. Var
  1282.   p : Byte;
  1283.   s : string;
  1284.   i : Integer;
  1285.  
  1286. Begin
  1287.   Write('Enter serial port number [1..4] : '); readln(p);
  1288.   IF ComExist(p) And OpenCom(p,1024,1024)
  1289.     Then
  1290.       Begin
  1291.         ComParams(p,9600,8,'N',1);
  1292.  
  1293.       {----Hayes modems echo a cr,lf so lf as eoln char is easier to program.
  1294.            The cr is skipped also. Default eoln character is cr, equivalent
  1295.            to BP's readln procedure}
  1296.         ComSetEoln(p,c_lf);
  1297.         Writeln('Enter a Hayes Command, like ATX1');
  1298.         Readln(s);
  1299.         If (s<>'')
  1300.           THEN
  1301.             BEGIN
  1302.               Write('Sending...');
  1303.               ComWriteWithDelay(p,s+#13#10,500);
  1304.               Writeln(' ok, press <enter> to continue.');
  1305.  
  1306.               Readln;
  1307.               Repeat
  1308.                 Write('[',CombufferLeft(p,'I'):3,']');
  1309.                 ComReadln(p,s,255,false);
  1310.                 Writeln('[',ComBufferLeft(p,'I'):3,']',s);
  1311.               Until (ComBufferLeft(p,'I')=1024);
  1312.             END;
  1313.         CloseCom(p);
  1314.       End
  1315.     Else Writeln('Error opening COM',p,' port');
  1316. END.
  1317.  
  1318.  
  1319.